// 想要kanban加动画的看这里：https://www.bilibili.com/video/BV1zY411w7hs/
// 在线demo: https://codesteppe.github.io/kanban-dnd
// 源码地址：https://github.com/CodeSteppe/kanban-dnd
const droppables = document.querySelectorAll('.droppable');
const draggables = document.querySelectorAll('.draggable');
const transitionTime = 500;
let dragging;
let cloned;

document.body.style.setProperty('--transitionTime', transitionTime + 'ms');

function handleDragEnd() {
    if (!dragging) return;
    dragging.classList.add('will-remove');
    setTimeout(() => {
        dragging.remove();
        cleanClass('dragging');
    }, [transitionTime]);
}

function cleanClass(className) {
    const elements = document.querySelectorAll(`.${className}`);
    for (const el of elements) {
        el.classList.remove(className);
    }
}

//drag start
document.addEventListener('dragstart', e => {
    if (e.target.classList.contains('draggable')) {
        dragging = e.target;
        dragging.classList.add('dragging');
        cloned = dragging.cloneNode(true);
    }
});

//drag end
document.addEventListener('dragend', e => {
    cleanClass('dragging');
    cleanClass('new-added');
});

//drag over
droppables.forEach(droppable => {
    droppable.addEventListener('dragover', e => {
        e.preventDefault();
        //被移动到的column中，位置在dragging前面的最近的元素
        const frontSib = getClosestFrontSibling(droppable, e.clientY);
        //dragging在当前DOM树中的前面的元素
        const previousSib = dragging.previousElementSibling;
        if (frontSib) {
            //动画
            if (frontSib.nextElementSibling === cloned
                || frontSib === cloned
                || frontSib === previousSib) {
                return;
            }
            cloned.classList.add('new-added');
            // dragging.classList.add('new-added');
            //插入数据
            frontSib.insertAdjacentElement('afterend', cloned);
            // frontSib.insertAdjacentElement('afterend', dragging);
            handleDragEnd(dragging);
        } else {
            if (droppable.firstChild === cloned
                || droppable.firstChild === dragging) {
                return;
            }
            if (dragging.parentNode === droppable &&
                !previousSib) {
                return;
            }
            cloned.classList.add('new-added');
            //前面没有元素了，放第一的位置
            droppable.prepend(cloned);
            handleDragEnd(dragging);
        }
    });
});

//获取被移动元素前面最近的相邻元素
function getClosestFrontSibling(droppable, draggingY) {
    const siblings = droppable.querySelectorAll('.draggable:not(.dragging)');
    let result;

    for (const sibling of siblings) {
        const box = sibling.getBoundingClientRect();
        //获取sibing的中心Y
        const boxCenterY = box.y + box.height / 2;
        if (draggingY >= boxCenterY) {
            result = sibling;
        } else {
            //draggingY < boxCenterY说明：要么已找到前方最近的相邻元素，要么被拖到第一的位置
            return result;
        }
    }
    return result;
}